import time
from typing import Union
from appium.webdriver.webelement import WebElement
from appium.webdriver.common.mobileby import MobileBy
from appium.webdriver.webdriver import WebDriver


class CommonBasePage:
    appium_driver = None

    def __init__(self, appium_driver: WebDriver = None):
        self.appium_driver = appium_driver

    def find_app_element(self, *args) -> WebElement:
        """
        封装元素定位，找单个元素
        :param args:
        :return:
        """
        if str(args[0]) == 'CSS' or str(args[0]).lower() == 'css':
            return self.appium_driver.find_element(MobileBy.CSS_SELECTOR, args[1])
        elif str(args[0]) == 'Name' or str(args[0]).lower() == 'name':
            return self.appium_driver.find_element(MobileBy.NAME, args[1])
        elif str(args[0]) == 'ID' or str(args[0]).lower() == 'id':
            return self.appium_driver.find_element(MobileBy.ID, args[1])
        elif str(args[0]) == 'TAG_NAME' or str(args[0]).lower() == 'tag_name':
            return self.appium_driver.find_element(MobileBy.TAG_NAME, args[1])
        elif str(args[0]) == 'XPATH' or str(args[0]).lower() == 'xpath':
            return self.appium_driver.find_element(MobileBy.XPATH, args[1])
        elif str(args[0]) == 'LINK_TEXT' or str(args[0]).lower() == 'link_text':
            return self.appium_driver.find_element(MobileBy.LINK_TEXT, args[1])
        elif str(args[0]) == 'CLASS_NAME' or str(args[0]).lower() == 'class_name':
            return self.appium_driver.find_element(MobileBy.CLASS_NAME, args[1])
        elif str(args[0]) == 'PARTIAL_LINK_TEXT' or str(args[0]).lower() == 'partial_link_text':
            return self.appium_driver.find_element(MobileBy.PARTIAL_LINK_TEXT, args[1])
        else:
            raise TypeError("参数类型不正确")

    def find_app_elements(self, *args: str) -> Union[list[WebElement], list]:
        """
        封装元素定位，找多个元素
        :param args:
        :return:
        """
        if str(args[0]) == 'CSS' or str(args[0]).lower() == 'css':
            return self.appium_driver.find_elements(MobileBy.CSS_SELECTOR, args[1])
        elif str(args[0]) == 'Name' or str(args[0]).lower() == 'name':
            return self.appium_driver.find_elements(MobileBy.NAME, args[1])
        elif str(args[0]) == 'ID' or str(args[0]).lower() == 'id':
            return self.appium_driver.find_elements(MobileBy.ID, args[1])
        elif str(args[0]) == 'TAG_NAME' or str(args[0]).lower() == 'tag_name':
            return self.appium_driver.find_elements(MobileBy.TAG_NAME, args[1])
        elif str(args[0]) == 'XPATH' or str(args[0]).lower() == 'xpath':
            return self.appium_driver.find_elements(MobileBy.XPATH, args[1])
        elif str(args[0]) == 'LINK_TEXT' or str(args[0]).lower() == 'link_text':
            return self.appium_driver.find_elements(MobileBy.LINK_TEXT, args[1])
        elif str(args[0]) == 'CLASS_NAME' or str(args[0]).lower() == 'class_name':
            return self.appium_driver.find_elements(MobileBy.CLASS_NAME, args[1])
        elif str(args[0]) == 'PARTIAL_LINK_TEXT' or str(args[0]).lower() == 'partial_link_text':
            return self.appium_driver.find_elements(MobileBy.PARTIAL_LINK_TEXT, args[1])
        else:
            raise TypeError("参数类型不正确")

    def find_app_element_and_click(self, args: tuple) -> None:
        self.find_app_element(*args).click()

    def find_app_element_and_input(self,args: tuple,value) -> None:
        self.find_app_element(*args).send_keys(value)

    def find_app_element_and_get_attr(self,args: tuple,attr='text'):
        return self.find_app_element(*args).get_attribute(attr)

    def swipe_down(self, num=5):
        """
        下滑
        :param num:
        :return:
        """
        height = self.appium_driver.get_window_rect()['height']
        width = self.appium_driver.get_window_rect()['width']
        for i in range(num):
            self.appium_driver.swipe(int(width / 2), int(height * 0.8), int(width / 2), int(height * int(2 / 3)),
                                     duration=2000)

    @staticmethod
    def wait(custom_secs: float = 5.00):
        time.sleep(custom_secs)
